<template>
  <div>
    <el-upload :action="state.uploadUrl" :before-upload="handleBeforeUpload" :on-success="handleUploadSuccess"
      :on-error="handleUploadError" name="file" :show-file-list="false" style="display: none"
      ref="upload" v-show="props.type == 'url'">
    </el-upload>
    <div class="editor" ref="editor" :style="styles"></div>
  </div>
</template>

<script setup lang="ts">
import Quill from "quill";
import "quill/dist/quill.core.css";
import "quill/dist/quill.snow.css";
import "quill/dist/quill.bubble.css";
import { computed, nextTick, onMounted, onUnmounted, reactive, ref, watch } from "vue";
import { ElMessage, ElUpload, FormInstance } from 'element-plus'
const emitEvent = defineEmits(['input','on-change','on-text-change','on-selection-change','on-editor-change'])
const props = defineProps({
  /* 编辑器的内容 */
  value: {
    type: String,
    default: "",
  },
  /* 高度 */
  height: {
    type: Number,
    default: null,
  },
  /* 最小高度 */
  minHeight: {
    type: Number,
    default: null,
  },
  /* 只读 */
  readOnly: {
    type: Boolean,
    default: false,
  },
  // 上传文件大小限制(MB)
  fileSize: {
    type: Number,
    default: 5,
  },
  /* 类型（base64格式、url格式） */
  type: {
    type: String,
    default: "url",
  }
})
const state = reactive({
  uploadUrl: import.meta.env.VITE_PUBLIC_UPLOAD, // 上传的图片服务器地址
  Quill: null as any,
  quill: null as any,
  currentValue: "" as string | undefined,
  uploadType: '',
  options: {
    theme: "snow",
    bounds: document.body,
    debug: "warn",
    modules: {
      // 工具栏配置

    },
    placeholder: "请输入内容",
    readOnly: props.readOnly,
  }
})

const editor = ref<any>()
const upload = ref<any>()

const styles = computed(() => {

  let style = {} as any;
  if (props.minHeight) {
    style.minHeight = `${props.minHeight}px`;
  }
  if (props.height) {
    style.height = `${props.height}px`;
  }
  return style;
})
// watch(() => props.value, (val) => {
//   if (val !== state.currentValue) {
//     state.currentValue = val === null ? "" : val;
//     if (state.Quill) {
//       state.Quill.pasteHTML(state.currentValue);
//     }
//   }
// }, { immediate: true })

onMounted(() => {
  init();
})
onUnmounted(() => {  
  state.Quill = null
})

async function init() {

  state.Quill = new Quill(editor.value, state.options);
  // 如果设置了上传地址则自定义图片上传事件
  if (props.type == 'url') {
    let toolbar = state.Quill.getModule("toolbar");
    toolbar.addHandler("image", (value) => {
      state.uploadType = "image";
      if (value) {
        upload.value?.$el.children[0].click();
      } else {
        state.quill.format("image", false);
      }
    });
  }
  // state.Quill.pasteHTML(state.currentValue);
  state.Quill.on("text-change", (delta:any, oldDelta:any, source:any) => {
    const html = editor.value?.children[0].innerHTML;
    const text = state.Quill.getText();
    const quill = state.Quill;
    state.currentValue = html;
    emitEvent("input", html);
    emitEvent("on-change", { html, text, quill });
  });
  // state.Quill.on("text-change", (delta, oldDelta, source) => {
  //   emitEvent("on-text-change", delta, oldDelta, source);
  // });
  // state.Quill.on("selection-change", (range, oldRange, source) => {
  //   emitEvent("on-selection-change", range, oldRange, source);
  // });
  // state.Quill.on("editor-change", (eventName, ...args) => {
  //   emitEvent("on-editor-change", eventName, ...args);
  // });
}
// 上传前校检格式和大小
function handleBeforeUpload(file) {
  // 校检文件大小
  if (props.fileSize) {
    const isLt = file.size / 1024 / 1024 < props.fileSize;
    if (!isLt) {
      ElMessage.error(`上传文件大小不能超过 ${props.fileSize} MB!`);
      return false;
    }
  }
  return true;
}
function handleUploadSuccess(res, file) {
  // 获取富文本组件实例
  let quill = state.Quill;
  // 如果上传成功
  if (res.code == 200) {
    // 获取光标所在位置
    let length = quill.getSelection().index;
    // 插入图片  res.url为服务器返回的图片地址
    quill.insertEmbed(length, "image", res.data.url);
    // 调整光标到最后
    quill.setSelection(length + 1);
  } else {
    ElMessage.error("图片插入失败");
  }
}
function handleUploadError() {
  ElMessage.error("图片插入失败");
}

</script>

<style>
.editor,
.ql-toolbar {
  white-space: pre-wrap !important;
  line-height: normal !important;
}

.quill-img {
  display: none;
}

.ql-snow .ql-tooltip[data-mode="link"]::before {
  content: "请输入链接地址:";
}

.ql-snow .ql-tooltip.ql-editing a.ql-action::after {
  border-right: 0px;
  content: "保存";
  padding-right: 0px;
}

.ql-snow .ql-tooltip[data-mode="video"]::before {
  content: "请输入视频地址:";
}

.ql-snow .ql-picker.ql-size .ql-picker-label::before,
.ql-snow .ql-picker.ql-size .ql-picker-item::before {
  content: "14px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="small"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="small"]::before {
  content: "10px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="large"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="large"]::before {
  content: "18px";
}

.ql-snow .ql-picker.ql-size .ql-picker-label[data-value="huge"]::before,
.ql-snow .ql-picker.ql-size .ql-picker-item[data-value="huge"]::before {
  content: "32px";
}

.ql-snow .ql-picker.ql-header .ql-picker-label::before,
.ql-snow .ql-picker.ql-header .ql-picker-item::before {
  content: "文本";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="1"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="1"]::before {
  content: "标题1";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="2"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="2"]::before {
  content: "标题2";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="3"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="3"]::before {
  content: "标题3";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="4"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="4"]::before {
  content: "标题4";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="5"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="5"]::before {
  content: "标题5";
}

.ql-snow .ql-picker.ql-header .ql-picker-label[data-value="6"]::before,
.ql-snow .ql-picker.ql-header .ql-picker-item[data-value="6"]::before {
  content: "标题6";
}

.ql-snow .ql-picker.ql-font .ql-picker-label::before,
.ql-snow .ql-picker.ql-font .ql-picker-item::before {
  content: "标准字体";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="serif"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="serif"]::before {
  content: "衬线字体";
}

.ql-snow .ql-picker.ql-font .ql-picker-label[data-value="monospace"]::before,
.ql-snow .ql-picker.ql-font .ql-picker-item[data-value="monospace"]::before {
  content: "等宽字体";
}
</style>
